// ----------------------------------------------------------------------------------
// Microsoft Developer & Platform Evangelism
// 
// Copyright (c) Microsoft Corporation. All rights reserved.
// 
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
// ----------------------------------------------------------------------------------

namespace FederationMetadataEditor
{
    using System;
    using System.Configuration;
    using System.Diagnostics;
    using System.IO;
    using System.Windows.Forms;
    using Microsoft.Win32;

    public partial class GenerateCertificateForm : Form
    {
        private SelfSTSSection stsSection;
        private System.Configuration.Configuration config;

        public GenerateCertificateForm()
        {
            this.InitializeComponent();
            this.config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            this.stsSection = this.config.GetSection("SelfSTSSettings") as SelfSTSSection;
        }

        public string CertificateFileName { get; set; }
        
        public string CertificatePassword { get; set; }

        private static void DeleteIfExists(string file)
        {            
            if (File.Exists(file)) 
            { 
                File.Delete(file); 
            }
        }
        
        private static void RunProcess(string path, string arguments)
        {
            var info = new ProcessStartInfo(path, arguments);
            info.CreateNoWindow = true;
            info.UseShellExecute = false;
            var process = Process.Start(info);
            process.WaitForExit();
        }

        private static string GetRegistryKeyValue(string key, string item)
        {
            var regKey = Registry.LocalMachine.OpenSubKey(key);
            if (regKey != null)
            {
                return regKey.GetValue(item).ToString();
            }

            return null;
        }

        private string GetSDKPath()
        {
            string path;

            path = GetRegistryKeyValue(@"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.0A", "InstallationFolder");
            if (string.IsNullOrEmpty(path))
            {
                path = GetRegistryKeyValue(@"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A", "InstallationFolder");
            }

            if (string.IsNullOrEmpty(path))
            {
                MessageBox.Show("The Windows SDK v6.0A or v7.0A is not installed", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return path;
        }

        private void BtnOK_Click(object sender, EventArgs e)
        {
            string subjectName = this.ucGenerateCertificate.SubjectName;
            string password = this.ucGenerateCertificate.Password;
            string makecert = Path.Combine(this.GetSDKPath(), "Bin\\makecert.exe");
            string cert2spc = Path.Combine(this.GetSDKPath(), "Bin\\cert2spc.exe");
            string pvk2pfx = Path.Combine(this.GetSDKPath(), "Bin\\pvk2pfx.exe");

            DeleteIfExists(string.Format("{0}.spc", subjectName));
            DeleteIfExists(string.Format("{0}.cer", subjectName));
            DeleteIfExists(string.Format("{0}.pvk", subjectName));
            DeleteIfExists(string.Format("{0}.pfx", subjectName));

            RunProcess(makecert, string.Format("-r -n CN={0} -sv {0}.pvk -sky exchange -a sha1 {0}.cer", subjectName));
            RunProcess(cert2spc, string.Format("{0}.cer {0}.spc", subjectName));
            RunProcess(pvk2pfx, string.Format("-spc {0}.spc -pvk {0}.pvk -pfx {0}.pfx -pi {1} -f", subjectName, password));

            this.stsSection.SigningCertificate = this.CertificateFileName = string.Format("{0}.pfx", subjectName);
            this.stsSection.SigningCertificatePassword = this.CertificatePassword = password;
            this.config.Save(ConfigurationSaveMode.Full);

            DeleteIfExists(string.Format("{0}.spc", subjectName));
            DeleteIfExists(string.Format("{0}.cer", subjectName));
            DeleteIfExists(string.Format("{0}.pvk", subjectName));

            this.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.Close();
        }

        private void BtnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.Close();
        }        
    }
}